package com.ellison.zookeeperdemo.queue;

import org.I0Itec.zkclient.ExceptionUtil;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkNoNodeException;

import java.util.Comparator;
import java.util.List;

/**
 * @Classname FIFOQueue
 * @Description TODO
 * @Author xx
 * Date 2021/6/19 21:15
 * Version 1.0
 */
public class FIFOQueue<T> {

    protected final ZkClient zkClient;

    protected final String root;

    protected static final String node_name = "n_";

    public FIFOQueue(ZkClient zkClient, String root) {
        this.root = root;
        this.zkClient = zkClient;
    }

    private int size() {
        return zkClient.getChildren(root).size();
    }

    private boolean isEmpty() {
        return zkClient.getChildren(root).size() == 0;
    }

    public boolean push(T data) throws Exception {
        String nodepath = root.concat("/").concat(node_name);
        try {
            zkClient.createEphemeralSequential(nodepath, data);
            System.out.println(Thread.currentThread().getName() + "--> 成功push数据！！");
        } catch (ZkNoNodeException e) {
            zkClient.createPersistent(root);
            push(data);
        } catch (Exception e) {
            throw ExceptionUtil.convertToRuntimeException(e);
        }
        return true;
    }

    public T poll() throws Exception {
        List<String> children = zkClient.getChildren(root);
        if (children.size() == 0) {
            return null;
        }
        children.sort(Comparator.comparing(o -> getNodeNumber(o, node_name)));

        try {
            String polldata = children.get(0);
            String fullpath = root.concat("/").concat(polldata);
            T data = (T) zkClient.readData(fullpath);
            zkClient.delete(fullpath);
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getNodeNumber(String string, String nodeName) {
        int index = string.lastIndexOf(nodeName);
        if (index >= 0) {
            index += node_name.length();
            return index <= string.length() ? string.substring(index) : "";
        }
        return string;
    }
}
